package com.indexingsystem.db.mongoDB.impl;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.regex.Pattern;

import org.apache.commons.lang3.StringUtils;
import org.bson.Document;
import org.bson.conversions.Bson;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.indexingsystem.boss.Vo.GamesTableVo;
import com.indexingsystem.boss.Vo.GamesVo;
import com.indexingsystem.boss.entity.AuditLogs;
import com.indexingsystem.boss.entity.DhResourceauditlogs;
import com.indexingsystem.boss.entity.DhTodayStorageInfos;
import com.indexingsystem.boss.entity.Games;
import com.indexingsystem.boss.entity.ResCategoryRelations;
import com.indexingsystem.boss.entity.ResourceRelations;
import com.indexingsystem.boss.entity.Resources;
import com.indexingsystem.boss.entity.SpecialResourceDatas;
import com.indexingsystem.boss.logback.LogCvt;
import com.indexingsystem.boss.utils.JsonUtils;
import com.indexingsystem.db.mongoDB.MongoManager;
import com.indexingsystem.db.mongoDB.comon.MongoDBUtils;
import com.indexingsystem.db.mongoDB.comon.MongoTableName;
import com.indexingsystem.db.mongoDB.po.GamesResourceMongoVo;
import com.mongodb.BasicDBObject;
import com.mongodb.client.model.Filters;
import com.mongodb.client.model.UpdateOptions;

/**
 * 存储游戏结构mongo内存操作实现类
 * 
 * @author Administrator
 * 
 */
public class GamesResourceMongo {

	/**
	 * 游戏资源mongo新增单条数据.
	 * 
	 * @param articlesResourceMongoVo
	 * @throws Exception
	 */
	public static void addGames(GamesResourceMongoVo gamesResourceMongoVo, String institutionId) throws Exception {
		MongoManager manager = new MongoManager();
		LogCvt.debug( MongoTableName.DH_GAMES_RESOURCE + "添加 ------->" + com.alibaba.fastjson.JSON.toJSONString( gamesResourceMongoVo, true ) );
		if (null != gamesResourceMongoVo) {
			Document mainDocument = new Document();
			mainDocument.put( "_id", gamesResourceMongoVo.getResId() );
			mainDocument.put( "resId", gamesResourceMongoVo.getResId() );
			mainDocument.put( "resTypeId", gamesResourceMongoVo.getResTypeId() );
			mainDocument.put( "resTable", gamesResourceMongoVo.getResTable() );
			mainDocument.put( "institutionId", institutionId );

			Document gamesDoc = MongoDBUtils.transform2Doc( gamesResourceMongoVo.getGames() );
			mainDocument.put( "games", gamesDoc );

			Document resourcesDoc = MongoDBUtils.transform2Doc( gamesResourceMongoVo.getResources() );
			mainDocument.put( "resources", resourcesDoc );

			Document resourceauditlogsDoc = MongoDBUtils.transform2Doc( gamesResourceMongoVo.getResourceauditlogs() );
			mainDocument.put( "resourceauditlogs", resourceauditlogsDoc );

			Document auditLogsDoc = MongoDBUtils.transform2Doc( gamesResourceMongoVo.getAuditLogs() );
			mainDocument.put( "auditLogs", auditLogsDoc );

			Document todayStorageInfosDoc = MongoDBUtils.transform2Doc( gamesResourceMongoVo.getTodayStorageInfos() );
			mainDocument.put( "todayStorageInfos", todayStorageInfosDoc );

			List<Document> specialResourceDatasDocList = new ArrayList<Document>();
			if (null != gamesResourceMongoVo.getDhSpecialResourceDatasList() && gamesResourceMongoVo.getDhSpecialResourceDatasList().size() > 0) {
				for (SpecialResourceDatas specialResourceDatas : gamesResourceMongoVo.getDhSpecialResourceDatasList()) {
					Document specialResourceDatasDoc = MongoDBUtils.transform2Doc( specialResourceDatas );
					specialResourceDatasDocList.add( specialResourceDatasDoc );
				}
			}
			mainDocument.put( "dhSpecialResourceDatasList", specialResourceDatasDocList );

			List<Document> dhResourceRelationsDocList = new ArrayList<Document>();
			if (null != gamesResourceMongoVo.getDhResourceRelationsList() && gamesResourceMongoVo.getDhResourceRelationsList().size() > 0) {
				for (ResourceRelations resourceRelations : gamesResourceMongoVo.getDhResourceRelationsList()) {
					Document resourceRelationsDoc = MongoDBUtils.transform2Doc( resourceRelations );
					dhResourceRelationsDocList.add( resourceRelationsDoc );
				}
			}
			mainDocument.put( "dhResourceRelationsList", dhResourceRelationsDocList );

			List<Document> resCategoryRelationsDocList = new ArrayList<Document>();
			if (null != gamesResourceMongoVo.getResCategoryRelationsList() && gamesResourceMongoVo.getResCategoryRelationsList().size() > 0) {
				for (ResCategoryRelations resourceCategoryRelations : gamesResourceMongoVo.getResCategoryRelationsList()) {
					Document resCategoryRelationsDoc = MongoDBUtils.transform2Doc( resourceCategoryRelations );
					resCategoryRelationsDocList.add( resCategoryRelationsDoc );
				}
			}
			mainDocument.put( "resCategoryRelationsList", resCategoryRelationsDocList );

			manager.add( mainDocument, MongoTableName.DH_GAMES_RESOURCE );
		}
	}

	/**
	 * 入库管理单一修改游戏资源mongo修改.
	 * 
	 * @param articlesResourceMongoVo
	 * @throws Exception
	 */
	public static void updateGames(GamesResourceMongoVo gamesResourceMongoVo, String institutionId) throws Exception {
		MongoManager manager = new MongoManager();
		LogCvt.debug( MongoTableName.DH_GAMES_RESOURCE + "修改 ------->" + com.alibaba.fastjson.JSON.toJSONString( gamesResourceMongoVo, true ) );
		if (null != gamesResourceMongoVo) {
			Document mainDocument = new Document();
			mainDocument.put( "resId", gamesResourceMongoVo.getResId() );
			mainDocument.put( "resTypeId", gamesResourceMongoVo.getResTypeId() );
			mainDocument.put( "resTable", gamesResourceMongoVo.getResTable() );
			mainDocument.put( "institutionId", institutionId );

			Document gamesDoc = MongoDBUtils.transform2Doc( gamesResourceMongoVo.getGames() );
			mainDocument.put( "games", gamesDoc );

			Document resourcesDoc = MongoDBUtils.transform2Doc( gamesResourceMongoVo.getResources() );
			mainDocument.put( "resources", resourcesDoc );

			Document resourceauditlogsDoc = MongoDBUtils.transform2Doc( gamesResourceMongoVo.getResourceauditlogs() );
			mainDocument.put( "resourceauditlogs", resourceauditlogsDoc );

			Document auditLogsDoc = MongoDBUtils.transform2Doc( gamesResourceMongoVo.getAuditLogs() );
			mainDocument.put( "auditLogs", auditLogsDoc );

			Document todayStorageInfosDoc = MongoDBUtils.transform2Doc( gamesResourceMongoVo.getTodayStorageInfos() );
			mainDocument.put( "todayStorageInfos", todayStorageInfosDoc );

			List<Document> specialResourceDatasDocList = new ArrayList<Document>();
			if (null != gamesResourceMongoVo.getDhSpecialResourceDatasList() && gamesResourceMongoVo.getDhSpecialResourceDatasList().size() > 0) {
				for (SpecialResourceDatas specialResourceDatas : gamesResourceMongoVo.getDhSpecialResourceDatasList()) {
					Document specialResourceDatasDoc = MongoDBUtils.transform2Doc( specialResourceDatas );
					specialResourceDatasDocList.add( specialResourceDatasDoc );
				}
			}
			mainDocument.put( "dhSpecialResourceDatasList", specialResourceDatasDocList );

			List<Document> dhResourceRelationsDocList = new ArrayList<Document>();
			if (null != gamesResourceMongoVo.getDhResourceRelationsList() && gamesResourceMongoVo.getDhResourceRelationsList().size() > 0) {
				for (ResourceRelations resourceRelations : gamesResourceMongoVo.getDhResourceRelationsList()) {
					Document resourceRelationsDoc = MongoDBUtils.transform2Doc( resourceRelations );
					dhResourceRelationsDocList.add( resourceRelationsDoc );
				}
			}
			mainDocument.put( "dhResourceRelationsList", dhResourceRelationsDocList );

			List<Document> resCategoryRelationsDocList = new ArrayList<Document>();
			if (null != gamesResourceMongoVo.getResCategoryRelationsList() && gamesResourceMongoVo.getResCategoryRelationsList().size() > 0) {
				for (ResCategoryRelations resourceCategoryRelations : gamesResourceMongoVo.getResCategoryRelationsList()) {
					Document resCategoryRelationsDoc = MongoDBUtils.transform2Doc( resourceCategoryRelations );
					resCategoryRelationsDocList.add( resCategoryRelationsDoc );
				}
			}
			mainDocument.put( "resCategoryRelationsList", resCategoryRelationsDocList );

			UpdateOptions options = new UpdateOptions().upsert( true );
			Bson bson = Filters.and( Filters.eq( "resId", gamesResourceMongoVo.getResId() ), Filters.eq( "institutionId", institutionId ) );
			Document doc = new Document( "$set", mainDocument );
			manager.updateOne( bson, doc, options, MongoTableName.DH_GAMES_RESOURCE );
		}
	}

	/**
	 * 批量删除游戏更新mongodb.
	 * 
	 * @param map
	 * @return
	 */
	public static void deleteGamesByIds(List<String> resIdList, String institutionId) {
		MongoManager manager = new MongoManager();
		Bson bson = Filters.and( Filters.in( "resId", resIdList ), Filters.eq( "institutionId", institutionId ) );
		manager.deleteAll( bson, MongoTableName.DH_GAMES_RESOURCE );
	}

	/**
	 * 返回游戏列表
	 * 
	 * @param map
	 * @return
	 */
	public static List<GamesTableVo> findGamesByPage(GamesVo gamesVo, String institutionId) {
		MongoManager manager = new MongoManager();
		List<GamesTableVo> gamesTableVosList = null;
		LogCvt.debug( MongoTableName.DH_GAMES_RESOURCE + "查游戏列表 ------->" );
		BasicDBObject basicDBObject = new BasicDBObject();
		basicDBObject.put( "resTable", "Games" );
		basicDBObject.put( "institutionId", institutionId );

		if (StringUtils.isNotBlank( gamesVo.getQueryCriteria() )) {
			Pattern pattern = Pattern.compile( ".*" + gamesVo.getQueryCriteria() + ".*", Pattern.CASE_INSENSITIVE );
			basicDBObject.put( "resources.resName", pattern );
		}
		if (null != gamesVo.getStatus()) {
			basicDBObject.put( "resources.status", gamesVo.getStatus() );
		}
		if (StringUtils.isNotBlank( gamesVo.getTerminalCode() )) {
			basicDBObject.put( "dhSpecialResourceDatasList.terminalCode", gamesVo.getTerminalCode() );
		}
		if (StringUtils.isNotBlank( gamesVo.getFileType() )) {
			Pattern pattern = Pattern.compile( ".*" + gamesVo.getFileType() + ".*", Pattern.CASE_INSENSITIVE );
			basicDBObject.put( "games.fileType", pattern );
		}
		if (StringUtils.isNotBlank( gamesVo.getGamesType() )) {
			Pattern pattern = Pattern.compile( ".*" + gamesVo.getGamesType() + ".*", Pattern.CASE_INSENSITIVE );
			basicDBObject.put( "games.gamesType", pattern );
		}

		// 排序条件
		Document sortDocument = new Document();
		sortDocument.put( "resources.publishDate", -1 );
		// 不显示的字段
		Document fetchFields = new Document();
		fetchFields.put( "_id", 0 );
		fetchFields.put( "games", 1 );
		fetchFields.put( "resources", 1 );
		/* fetchFields.put( "dhSpecialResourceDatasList", 0 ); */
		List<Document> documentsList = manager.queryPages( MongoTableName.DH_GAMES_RESOURCE, basicDBObject, sortDocument, fetchFields,
				gamesVo.getPageNumber(), gamesVo.getPageSize() );
		try {
			if (null != documentsList && documentsList.size() > 0) {
				gamesTableVosList = new ArrayList<GamesTableVo>();
				for (Document document : documentsList) {
					GamesTableVo gamesTableVo = new GamesTableVo();

					Games games = new Games();
					games = (Games) MongoDBUtils.setFieldValue( games, Document.parse( JsonUtils.toJson( document.get( "games" ) ) ) );
					if (null != games) {
						gamesTableVo.setGamesType( games.getGamesType() );
						gamesTableVo.setGamesSize( games.getGamesSize() );
						gamesTableVo.setFileType( games.getFileType() );
					}

					Resources resources = new Resources();
					resources = (Resources) MongoDBUtils.setFieldValue( resources, Document.parse( JsonUtils.toJson( document.get( "resources" ) ) ) );
					if (null != resources) {
						gamesTableVo.setThumbnail( resources.getThumbnail() );
						gamesTableVo.setKeyword( resources.getKeyword() );
						gamesTableVo.setPublishDate( resources.getPublishDate() );
						gamesTableVo.setResName( resources.getResName() );
						gamesTableVo.setStatus( resources.getStatus() );
						gamesTableVo.setResId( resources.getResId() );
					}
					if (!gamesTableVosList.contains( gamesTableVo )) {
						gamesTableVosList.add( gamesTableVo );
					}
				}
			}
		} catch (Exception ex) {
			ex.printStackTrace();
		}

		LogCvt.debug( "查询 gamesTableVosList 结果:" + JSON.toJSONString( gamesTableVosList, true ) );
		return gamesTableVosList;
	}

	/**
	 * 返回游戏总数量.
	 * 
	 * @param map
	 * @return
	 */
	public static Integer findGamesMaxCount(GamesVo gamesVo, String institutionId) {
		MongoManager manager = new MongoManager();
		LogCvt.debug( MongoTableName.DH_GAMES_RESOURCE + "查游戏列表总数量 ------->" );
		BasicDBObject basicDBObject = new BasicDBObject();
		basicDBObject.put( "resTable", "Games" );
		basicDBObject.put( "institutionId", institutionId );

		if (StringUtils.isNotBlank( gamesVo.getQueryCriteria() )) {
			Pattern pattern = Pattern.compile( ".*" + gamesVo.getQueryCriteria() + ".*", Pattern.CASE_INSENSITIVE );
			basicDBObject.put( "resources.resName", pattern );
		}
		if (null != gamesVo.getStatus()) {
			basicDBObject.put( "resources.status", gamesVo.getStatus() );
		}
		if (StringUtils.isNotBlank( gamesVo.getTerminalCode() )) {
			basicDBObject.put( "dhSpecialResourceDatasList.terminalCode", gamesVo.getTerminalCode() );
		}
		if (StringUtils.isNotBlank( gamesVo.getFileType() )) {
			Pattern pattern = Pattern.compile( ".*" + gamesVo.getFileType() + ".*", Pattern.CASE_INSENSITIVE );
			basicDBObject.put( "games.fileType", pattern );
		}
		if (StringUtils.isNotBlank( gamesVo.getGamesType() )) {
			Pattern pattern = Pattern.compile( ".*" + gamesVo.getGamesType() + ".*", Pattern.CASE_INSENSITIVE );
			basicDBObject.put( "games.gamesType", pattern );
		}
		// 不显示的字段
		Document fetchFields = new Document();
		fetchFields.put( "_id", 0 );
		fetchFields.put( "resId", 1 );
		Integer maxCount = manager.queryAggregateListMaxCount( basicDBObject, MongoTableName.DH_GAMES_RESOURCE );

		LogCvt.debug( "查询 findGamesMaxCount 总数量:" + maxCount );
		return maxCount;
	}

	/**
	 * 通过resId获取游戏信息mongo缓存信息.
	 * 
	 * @param resId
	 * @return
	 */
	public static GamesResourceMongoVo selectGamesInfoByresId(String resId, String institutionId) throws Exception {
		MongoManager manager = new MongoManager();
		GamesResourceMongoVo gamesResourceMongoVo = null;
		if (StringUtils.isNotBlank( resId )) {
			Bson bson = Filters.and( Filters.in( "resId", resId ), Filters.eq( "institutionId", institutionId ) );

			LogCvt.info( MongoTableName.DH_GAMES_RESOURCE + "通过resId获取游戏信息条件:" + Arrays.asList( bson ).toString() );
			List<Document> documentsList = manager.queryAggregateList( bson, null, MongoTableName.DH_GAMES_RESOURCE );
			if (null != documentsList && documentsList.size() > 0) {
				gamesResourceMongoVo = new GamesResourceMongoVo();
				for (Document document : documentsList) {
					Resources resources = new Resources();
					resources = (Resources) MongoDBUtils.setFieldValue( resources, Document.parse( JsonUtils.toJson( document.get( "resources" ) ) ) );
					if (null != resources) {
						gamesResourceMongoVo.setResources( resources );
					}

					Games games = new Games();
					games = (Games) MongoDBUtils.setFieldValue( games, Document.parse( JsonUtils.toJson( document.get( "games" ) ) ) );
					if (null != games) {
						gamesResourceMongoVo.setGames( games );
					}

					DhResourceauditlogs resourceauditlogs = new DhResourceauditlogs();
					resourceauditlogs = (DhResourceauditlogs) MongoDBUtils.setFieldValue( resourceauditlogs,
							Document.parse( JsonUtils.toJson( document.get( "resourceauditlogs" ) ) ) );
					if (null != resourceauditlogs) {
						gamesResourceMongoVo.setResourceauditlogs( resourceauditlogs );
					}

					AuditLogs auditLogs = new AuditLogs();
					auditLogs = (AuditLogs) MongoDBUtils.setFieldValue( auditLogs, Document.parse( JsonUtils.toJson( document.get( "auditLogs" ) ) ) );
					if (null != auditLogs) {
						gamesResourceMongoVo.setAuditLogs( auditLogs );
					}

					DhTodayStorageInfos todayStorageInfos = new DhTodayStorageInfos();
					todayStorageInfos = (DhTodayStorageInfos) MongoDBUtils.setFieldValue( todayStorageInfos,
							Document.parse( JsonUtils.toJson( document.get( "todayStorageInfos" ) ) ) );
					if (null != todayStorageInfos) {
						gamesResourceMongoVo.setTodayStorageInfos( todayStorageInfos );
					}

					List<SpecialResourceDatas> dhSpecialResourceDatasList = new ArrayList<SpecialResourceDatas>();
					dhSpecialResourceDatasList = JSONArray.parseArray( JsonUtils.toJson( document.get( "dhSpecialResourceDatasList" ) ),
							SpecialResourceDatas.class );
					if (null != dhSpecialResourceDatasList && dhSpecialResourceDatasList.size() > 0) {
						gamesResourceMongoVo.setDhSpecialResourceDatasList( dhSpecialResourceDatasList );
					}

					List<ResourceRelations> dhResourceRelationsList = new ArrayList<ResourceRelations>();
					dhResourceRelationsList = JSONArray.parseArray( JsonUtils.toJson( document.get( "dhResourceRelationsList" ) ),
							ResourceRelations.class );
					if (null != dhResourceRelationsList && dhResourceRelationsList.size() > 0) {
						gamesResourceMongoVo.setDhResourceRelationsList( dhResourceRelationsList );
					}

					List<ResCategoryRelations> resCategoryRelationsList = new ArrayList<ResCategoryRelations>();
					resCategoryRelationsList = JSONArray.parseArray( JsonUtils.toJson( document.get( "resCategoryRelationsList" ) ),
							ResCategoryRelations.class );
					if (null != resCategoryRelationsList && resCategoryRelationsList.size() > 0) {
						gamesResourceMongoVo.setResCategoryRelationsList( resCategoryRelationsList );
					}
				}
			}
		}
		return gamesResourceMongoVo;
	}

	/**
	 * 通过resId获取游戏信息mongo缓存信息.
	 * 
	 * @param resId
	 * @return
	 */
	public static List<GamesResourceMongoVo> selectGamesInfoListByresId(List<String> resIdList, String institutionId) throws Exception {
		MongoManager manager = new MongoManager();
		List<GamesResourceMongoVo> gamesResourceMongoVoList = null;
		if (null != resIdList && resIdList.size() > 0) {
			Bson bson = Filters.and( Filters.in( "resId", resIdList ), Filters.eq( "institutionId", institutionId ) );

			LogCvt.info( MongoTableName.DH_GAMES_RESOURCE + "通过resId获取游戏信息条件:" + Arrays.asList( bson ).toString() );
			List<Document> documentsList = manager.queryAggregateList( bson, null, MongoTableName.DH_GAMES_RESOURCE );
			if (null != documentsList && documentsList.size() > 0) {
				gamesResourceMongoVoList = new ArrayList<GamesResourceMongoVo>();
				for (Document document : documentsList) {
					GamesResourceMongoVo gamesResourceMongoVo = new GamesResourceMongoVo();
					Resources resources = new Resources();
					resources = (Resources) MongoDBUtils.setFieldValue( resources, Document.parse( JsonUtils.toJson( document.get( "resources" ) ) ) );
					if (null != resources) {
						gamesResourceMongoVo.setResources( resources );
					}

					Games games = new Games();
					games = (Games) MongoDBUtils.setFieldValue( games, Document.parse( JsonUtils.toJson( document.get( "games" ) ) ) );
					if (null != games) {
						gamesResourceMongoVo.setGames( games );
					}

					DhResourceauditlogs resourceauditlogs = new DhResourceauditlogs();
					resourceauditlogs = (DhResourceauditlogs) MongoDBUtils.setFieldValue( resourceauditlogs,
							Document.parse( JsonUtils.toJson( document.get( "resourceauditlogs" ) ) ) );
					if (null != resourceauditlogs) {
						gamesResourceMongoVo.setResourceauditlogs( resourceauditlogs );
					}

					AuditLogs auditLogs = new AuditLogs();
					auditLogs = (AuditLogs) MongoDBUtils.setFieldValue( auditLogs, Document.parse( JsonUtils.toJson( document.get( "auditLogs" ) ) ) );
					if (null != auditLogs) {
						gamesResourceMongoVo.setAuditLogs( auditLogs );
					}

					DhTodayStorageInfos todayStorageInfos = new DhTodayStorageInfos();
					todayStorageInfos = (DhTodayStorageInfos) MongoDBUtils.setFieldValue( todayStorageInfos,
							Document.parse( JsonUtils.toJson( document.get( "todayStorageInfos" ) ) ) );
					if (null != todayStorageInfos) {
						gamesResourceMongoVo.setTodayStorageInfos( todayStorageInfos );
					}

					List<SpecialResourceDatas> dhSpecialResourceDatasList = new ArrayList<SpecialResourceDatas>();
					dhSpecialResourceDatasList = JSONArray.parseArray( JsonUtils.toJson( document.get( "dhSpecialResourceDatasList" ) ),
							SpecialResourceDatas.class );
					if (null != dhSpecialResourceDatasList && dhSpecialResourceDatasList.size() > 0) {
						gamesResourceMongoVo.setDhSpecialResourceDatasList( dhSpecialResourceDatasList );
					}

					List<ResourceRelations> dhResourceRelationsList = new ArrayList<ResourceRelations>();
					dhResourceRelationsList = JSONArray.parseArray( JsonUtils.toJson( document.get( "dhResourceRelationsList" ) ),
							ResourceRelations.class );
					if (null != dhResourceRelationsList && dhResourceRelationsList.size() > 0) {
						gamesResourceMongoVo.setDhResourceRelationsList( dhResourceRelationsList );
					}

					List<ResCategoryRelations> resCategoryRelationsList = new ArrayList<ResCategoryRelations>();
					resCategoryRelationsList = JSONArray.parseArray( JsonUtils.toJson( document.get( "resCategoryRelationsList" ) ),
							ResCategoryRelations.class );
					if (null != resCategoryRelationsList && resCategoryRelationsList.size() > 0) {
						gamesResourceMongoVo.setResCategoryRelationsList( resCategoryRelationsList );
					}

					if (!gamesResourceMongoVoList.contains( gamesResourceMongoVo )) {
						gamesResourceMongoVoList.add( gamesResourceMongoVo );
					}
				}
			}
		}
		return gamesResourceMongoVoList;
	}
}